from sqlalchemy import select, update, delete
from sqlalchemy.ext.asyncio import AsyncSession

from module_kylin.entity.do.future_strategy_position_do import KylinFutureStrategyPosition
from module_kylin.entity.vo.future_strategy_position_vo import (
    FutureStrategyPositionModel,
    FutureStrategyPositionPageQueryModel,
)
from utils.page_util import PageUtil


class FutureStrategyPositionDao:
    """
    期货策略仓位数据库操作层
    """

    @classmethod
    async def get_strategy_position_by_id(cls, db: AsyncSession, position_id: int):
        """
        根据ID获取策略仓位信息

        :param db: orm对象
        :param position_id: 仓位id
        :return: 策略仓位信息对象
        """
        position_info = (
            await db.execute(select(KylinFutureStrategyPosition).where(KylinFutureStrategyPosition.id == position_id))
        ).scalars().first()

        return position_info

    @classmethod
    async def get_strategy_position_by_info(cls, db: AsyncSession, position: FutureStrategyPositionModel):
        """
        根据策略实例名称和日期获取仓位信息

        :param db: orm对象
        :param position: 策略仓位对象
        :return: 策略仓位信息对象
        """
        query = select(KylinFutureStrategyPosition)
        
        if position.date:
            query = query.where(KylinFutureStrategyPosition.date == position.date)
        if position.strategy_instance:
            query = query.where(KylinFutureStrategyPosition.strategy_instance == position.strategy_instance)
        
        position_info = (await db.execute(query)).scalars().first()
        return position_info

    @classmethod
    async def get_strategy_position_list(cls, db: AsyncSession, query_model: FutureStrategyPositionPageQueryModel, is_page: bool = False):
        """
        获取策略仓位列表

        :param db: orm对象
        :param query_model: 查询参数对象
        :param is_page: 是否开启分页
        :return: 策略仓位列表
        """
        query = select(KylinFutureStrategyPosition)
        
        if query_model.date:
            query = query.where(KylinFutureStrategyPosition.date == query_model.date)
        if query_model.strategy_instance:
            # 使用ilike进行不区分大小写的模糊匹配
            query = query.where(KylinFutureStrategyPosition.strategy_instance.ilike(f'%{query_model.strategy_instance}%'))
        
        # 按日期降序排序
        query = query.order_by(KylinFutureStrategyPosition.date.desc())
        
        # 构建分页查询
        strategy_position_page = await PageUtil.paginate(db, query, query_model.page_num, query_model.page_size, is_page)
        
        return strategy_position_page

    @classmethod
    async def add_strategy_position(cls, db: AsyncSession, position: FutureStrategyPositionModel):
        """
        添加策略仓位

        :param db: orm对象
        :param position: 策略仓位对象
        :return: 操作结果
        """
        db_position = KylinFutureStrategyPosition(
            date=position.date,
            strategy_instance=position.strategy_instance,
            position=position.position,
            long_position=position.long_position,
            short_position=position.short_position
        )
        db.add(db_position)
        await db.flush()
        return db_position

    @classmethod
    async def update_strategy_position(cls, db: AsyncSession, position_id: int, position: FutureStrategyPositionModel):
        """
        更新策略仓位

        :param db: orm对象
        :param position_id: 仓位id
        :param position: 策略仓位对象
        :return: 操作结果
        """
        update_data = {}
        if position.date is not None:
            update_data[KylinFutureStrategyPosition.date] = position.date
        if position.strategy_instance is not None:
            update_data[KylinFutureStrategyPosition.strategy_instance] = position.strategy_instance
        if position.position is not None:
            update_data[KylinFutureStrategyPosition.position] = position.position
        if position.long_position is not None:
            update_data[KylinFutureStrategyPosition.long_position] = position.long_position
        if position.short_position is not None:
            update_data[KylinFutureStrategyPosition.short_position] = position.short_position
        
        await db.execute(
            update(KylinFutureStrategyPosition)
            .where(KylinFutureStrategyPosition.id == position_id)
            .values(update_data)
        )

    @classmethod
    async def delete_strategy_position(cls, db: AsyncSession, position_id: int):
        """
        删除策略仓位

        :param db: orm对象
        :param position_id: 仓位id
        :return: 操作结果
        """
        await db.execute(
            delete(KylinFutureStrategyPosition)
            .where(KylinFutureStrategyPosition.id == position_id)
        )

    @classmethod
    async def batch_delete_strategy_position(cls, db: AsyncSession, position_ids: list[int]):
        """
        批量删除策略仓位

        :param db: orm对象
        :param position_ids: 仓位id列表
        :return: 操作结果
        """
        await db.execute(
            delete(KylinFutureStrategyPosition)
            .where(KylinFutureStrategyPosition.id.in_(position_ids))
        )